/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package generators;

import java.io.*;
import java.util.*;
import data.LocalData;
import geography.Geography;
import simframe.util.Bucket;
//import generators.BankGenerator;
//import generators.BankGenerator.BankInfo;

/**
 *
 * @author Isaac Noble
 */
public class BankFileProcessor {

    public static void main(String args[]) throws IOException {
        ArrayList<String> bank_lines = new ArrayList<String>(100000);
        ArrayList<String> institution_lines = new ArrayList<String>(100000);
        File bank_file = new File("C:\\sim_works\\banks.csv");
        File institution_file = new File("C:\\sim_works\\Institutions.csv");
        Geography.Build();

        FileReader in = new FileReader(bank_file);
        BufferedReader reader = new BufferedReader(in);
        String line;
        while ((line = reader.readLine()) != null)
        {
            bank_lines.add(line);
        }
        in.close();
        reader.close();

        in = new FileReader(institution_file);
        reader = new BufferedReader(in);
        while ((line = reader.readLine()) != null)
        {
            institution_lines.add(line);
        }
        in.close();
        reader.close();

        Collection<Geography.City> cities = Geography.GetCities();

        HashMap<Integer, BankGenerator.BankInfo> banks = new HashMap<Integer, BankGenerator.BankInfo>();
        for(int i = 1; i < institution_lines.size(); i++)
        {
            String[] values = institution_lines.get(i).split(",");
            int active = Integer.parseInt(values[2]);
            int credit_card = Integer.parseInt(values[11]);
            if(active == 1 && credit_card == 0)
            {
                BankGenerator.BankInfo info = new BankGenerator.BankInfo();
                info.certificate = Integer.parseInt(values[1]);
                String city_name = values[6];
                Geography.City city_info;
                if (Geography.Exists(Geography.GeoType.CITY, city_name)) {
                    city_info = Geography.GetCity(city_name);
                } else
                {
                    city_info = GetChoice(city_name, cities);
                    Geography.AddAlias(Geography.GeoType.CITY, String.valueOf(city_info.GetGeoID()), city_name);
                }
                info.headquarters = city_info;
                info.name = values[12];
                try
                {
                    info.fed_num = Integer.parseInt(values[9]);
                    int state_charter = Integer.parseInt(values[14]);
                    if (state_charter == 1) {
                        info.state_charter = true;
                    } else {
                        info.state_charter = false;
                    }
                    
                    
                    if (values[3].length() > 1)
                    {
                        info.total_assets = Integer.parseInt(values[3]);
                    }
                    if (values[7].length() > 1)
                    {
                        info.deposits = Integer.parseInt(values[7]);
                    }
                    if (values[8].length() > 1)
                    {
                        info.equity = Integer.parseInt(values[8]);
                    }
                }
                catch(Exception e)
                {
                    continue;
                }

                info.AddCity(info.headquarters);

                banks.put(info.certificate, info);
            }
        }

        for(int i = 1; i < bank_lines.size(); i++)
        {
            String[] values = bank_lines.get(i).split(",");
            int cert = Integer.parseInt(values[1]);
            if(banks.containsKey(cert))
            {
                banks.get(cert).AddCity(values[2]);
            }
        }

        File out_file = LocalData.GetFile(LocalData.Input.BANK_FILE);
        FileWriter out = new FileWriter(out_file);
        BufferedWriter writer = new BufferedWriter(out);

        Iterator<BankGenerator.BankInfo> iter = banks.values().iterator();
        while(iter.hasNext())
        {
            BankGenerator.BankInfo info = iter.next();
            writer.write(info.ToCSV());
            writer.newLine();
        }
        writer.close();
        out.close();

    }

    private static Geography.City GetChoice(String city, Collection<Geography.City> cities) throws IOException
    {
        Iterator<Geography.City> iter = cities.iterator();

        Geography.City top_city = iter.next();
        int best_score = StringDist(city, top_city.GetName(), 0);

        while(iter.hasNext())
        {
            Geography.City acity = iter.next();
            Integer dist = StringDist(city, acity.GetName(), 0);
            if(dist <= best_score)
            {
                if(dist < best_score || acity.GetPopulation() > top_city.GetPopulation())
                {
                    top_city = acity;
                    best_score = dist;
                }
            }
        }

        return top_city;
    }

    public static int GetChoice(LinkedList<String> names, LinkedList<Integer> scores, String name) throws IOException
    {
        System.out.println("The best choice for: " + name);
        for(int i = 0; i < names.size(); i++)
        {
            System.out.println(i + ". " + names.get(i) + " with score " + scores.get(i));
        }
        System.out.print("? ");
        BufferedReader stdin = new java.io.BufferedReader(new InputStreamReader(System.in));
        String line = stdin.readLine();
        return Integer.parseInt(line);
    }

    public static void Insert(LinkedList<String> names, LinkedList<Integer> scores, String name, Integer score)
    {
        int i = 0;
        for(i = 0; i < 10 && i < scores.size(); i++)
        {
            if(score < scores.get(i))
            {
                break;
            }
        }

        scores.add(i, score);
        names.add(i, name);


        if(scores.size() > 10)
        {
            scores.removeLast();
            names.removeLast();
        }
    }

    private static int StringDist(String one, String two, int num_errors)
    {
        if(num_errors > 1)
        {
            return 2;
        }

        int index = 0;
        for(index = 0; index < one.length() && index < two.length(); index++)
        {
            if(one.charAt(index) != two.charAt(index))
            {
                break;
            }
        }
        if(index == one.length())
        {
            return 0;
        }
        if(index == two.length())
        {
            return 0;
        }

        String one_sub = one.substring(index);
        String two_sub = two.substring(index);

        String one_mutate = two_sub.charAt(0) + one_sub.substring(1);
        String one_delete = one_sub.substring(1);
        String two_delete = two_sub.substring(1);

        int mutate_dist = 1 + StringDist(one_mutate, two_sub, num_errors + 1);
        int deleteone_dist = 1 + StringDist(one_delete, two_sub, num_errors + 1);
        int deletetwo_dist = 1 + StringDist(one_sub, two_delete, num_errors + 1);

        int dist = Math.min(deletetwo_dist, mutate_dist);
        return Math.min(dist, deleteone_dist);
    }
}
